/*
 * Copyright (c) 2024 iSOFT INFRASTRUCTURE SOFTWARE CO., LTD.
 * easyAda is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */


#include <plat/config.h>
#include <tools/macros.h>
#include <core/addrspace.h>
#include <uapi/bootinfo.h>

extern unsigned long k_ro_start, k_ro_end;
extern unsigned long boot_physic_start, boot_physic_end;
extern unsigned long boot_end;
extern unsigned long k_text_start, k_text_end;
extern unsigned long k_rodata_start, k_rodata_end;
extern unsigned long k_data_start, k_data_end;
extern unsigned long rs_ro_start, rs_ro_end;
extern unsigned long k_ro_shared_start, k_ro_shared_end;
extern unsigned long k_rw_start, k_rw_end;
extern unsigned long k_stack_start, k_stack_end;
extern unsigned long bss_start, bss_end;
extern unsigned long k_shared_start, k_shared_end;
extern unsigned long k_ro_shared_end;
extern unsigned long k_rw_start;
extern unsigned long k_shared_end;

void clean_bss(void)
{
    long *src = (long *)&bss_start;
    long *dst = (long *)&bss_end;
    while (src < dst) {
        *src++ = 0;
    }
}
static unsigned long staic_value;
static unsigned long static_value1 = 100;

unsigned long long_value;
unsigned long value = 100;

const unsigned long const_value1;
const unsigned long const_value = 100;

volatile unsigned long volatile_value1;
volatile unsigned long volatile_value = 100;

extern void   uart_putchar(const char c);
void BOOTONLY relocate_data(void)
{
    dprintf("k_ro_start:%x,k_ro_end;%x\n", &k_ro_start, &k_ro_end);
    dprintf("boot_physic_start:%x,boot_physic_end;:%x\n", &boot_physic_start, &boot_physic_end);
    dprintf("boot_end;:%x\n", &boot_end);
    dprintf("k_text_start:%x,k_text_end;%x!\n", &k_text_start, &k_text_end);
    dprintf("k_rodata_start:%x,k_rodata_end:%x\n", &k_rodata_start, &k_rodata_end);
    dprintf("k_data_start:%x,k_data_end:%x\n", &k_data_start, &k_data_end);
    dprintf("rs_ro_start:%x,rs_ro_end;%x!\n", &rs_ro_start, &rs_ro_end);
    dprintf("k_ro_shared_start:%x,k_ro_shared_end:%x\n", &k_ro_shared_start, &k_ro_shared_end);
    dprintf("k_rw_start:%x,k_rw_end;%x!\n", &k_rw_start, &k_rw_end);
    dprintf("k_stack_start:%x,k_stack_end:%x\n", &k_stack_start, &k_stack_end);
    dprintf("bss_start:%x,bss_end;%x!\n", &bss_start, &bss_end);
    dprintf("k_shared_start:%x,k_shared_end:%x\n", &k_shared_start, &k_shared_end);

    dprintf("&staic_value:%x &static_value1:%x\n", &staic_value, &static_value1);
    dprintf("&long_value:%x &value:%x\n", &long_value, &value);
    dprintf("&const_value1:%x &const_value:%x\n", &const_value1, &const_value);
    dprintf("&volatile_value1:%x &volatile_value:%x\n", &volatile_value1, &volatile_value);

    dprintf("clean_bss!\n");
    clean_bss();
#ifdef MMU_ENABLE
    region_init(&kernelinfo.code, CONFIG_LOAD_ADDR, CONFIG_EXEC_ADDR,
                (unsigned long)&k_ro_shared_end - CONFIG_EXEC_ADDR);
    region_init(&kernelinfo.rwdata, (unsigned long)&k_rw_start - CONFIG_EXEC_ADDR + CONFIG_LOAD_ADDR,
                (unsigned long)&k_rw_start, (unsigned long)&k_rw_end - (unsigned long)&k_rw_start);

    region_init(&rootserverinfo.code, (unsigned long)&rs_ro_start - CONFIG_EXEC_ADDR + CONFIG_LOAD_ADDR,
                CONFIG_ROOTSERVER_EXEC_ADDR, (unsigned long)&rs_ro_end - (unsigned long)&rs_ro_start);

    region_init(&rootserverinfo.rwdata, (unsigned long)&k_shared_start - CONFIG_EXEC_ADDR + CONFIG_LOAD_ADDR,
                (unsigned long)&k_shared_start - CONFIG_EXEC_ADDR + CONFIG_ROOTSERVER_EXEC_ADDR,
                (unsigned long)&k_shared_end - (unsigned long)&k_shared_start);
#else
    region_init(&kernelinfo.code, CONFIG_LOAD_ADDR, CONFIG_LOAD_ADDR,
                (unsigned long)&k_ro_shared_end - (unsigned long)&k_ro_shared_start);
    region_init(&kernelinfo.rwdata, (unsigned long)&k_rw_start, (unsigned long)&k_rw_start,
                (unsigned long)&k_rw_end - (unsigned long)&k_rw_start);
    region_init(&rootserverinfo.code, (unsigned long)&rs_ro_start, (unsigned long)&rs_ro_start,
                (unsigned long)&rs_ro_end - (unsigned long)&rs_ro_start);

    region_init(&rootserverinfo.rwdata, (unsigned long)&k_shared_start, (unsigned long)&k_shared_start,
                (unsigned long)&k_shared_end - (unsigned long)&k_shared_start);
#endif

    dprintf("kernelinfo.code.vbase:%x,kernelinfo.code.pbase:%x,kernelinfo.code.size:%d\n", kernelinfo.code.vbase,
            kernelinfo.code.pbase, kernelinfo.code.size);
    dprintf("kernelinfo.rwdata.vbase:%x,kernelinfo.rwdata.pbase:%x,kernelinfo.rwdata.size:%d\n",
            kernelinfo.rwdata.vbase, kernelinfo.rwdata.pbase, kernelinfo.rwdata.size);

    dprintf("rootserverinfo.code.vbase:%x,rootserverinfo.code.pbase:%x,rootserverinfo.code.size:%d\n",
            rootserverinfo.code.vbase, rootserverinfo.code.pbase, rootserverinfo.code.size);
    dprintf("rootserverinfo.rwdata.vbase:%x,rootserverinfo.rwdata.pbase:%x,rootserverinfo.rwdata.size:%d\n",
            rootserverinfo.rwdata.vbase, rootserverinfo.rwdata.pbase, rootserverinfo.rwdata.size);
}
